
import { _decorator, AnimationClip, Component, Animation, SpriteFrame } from 'cc';
// import { FSM_PARAMS_TYPE_ENUM, PARAMS_NAME_ENUM } from '../../Enum';
import State from './State';
import { FSM_PARAMS_TYPE_ENUM } from '../Enum';
import { SubStateMachine } from './SubStateMachine';
// import State from '../../Base/State';
const { ccclass, property } = _decorator;

/**
 * Predefined variables
 * Name = PlayerState
 * DateTime = Wed Jun 28 2023 09:28:04 GMT+0800 (中国标准时间)
 * Author = zshzshzsh15
 * FileBasename = PlayerState.ts
 * FileBasenameNoExtension = PlayerState
 * URL = db://assets/Script/Player/PlayerState.ts
 * ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/
 *
 */

//状态机实现

type ParamsValueType = boolean | number


export interface IParamsValue {
    type: FSM_PARAMS_TYPE_ENUM,
    value: ParamsValueType
}


// type ParamsValueType= boolean  | number


// export interface IParamsValue{
//     type:FSM_PARAMS_TYPE_ENUM,
//     value:ParamsValueType   
// }


export const getInitParamsTrigger = () => {
    return {
        type: FSM_PARAMS_TYPE_ENUM.TRIGGER,
        value: false
    }
}


export const getInitParamsNumber = () => {
    return {
        type: FSM_PARAMS_TYPE_ENUM.NUMBER,
        value: 0
    }
}


@ccclass('StateMachine')
export abstract class StateMachine extends Component {
    animationsComponent: Animation

    //需要一个参数列表，和一个状态机列表

    //当前状态
    private _currentState: State | SubStateMachine = null

    //Promise的数组--为了await合理 
    waitingList: Array<Promise<SpriteFrame[]>> = []


    //需要一个参数列表，和一个状态机列表
    params: Map<string, IParamsValue> = new Map()  //参数列表

    stateMachines: Map<string, State | SubStateMachine> = new Map()  //状态机列表


    //获取参数
    getParams(parmasName: string) {
        if (this.params.has(parmasName)) {
            return this.params.get(parmasName).value
        }


    }


    //设置参数
    setParams(paramsName: string, value: ParamsValueType) {
        if (this.params.has(paramsName)) {
            // console.log(`有参数${paramsName}+++++${value}`)

            this.params.get(paramsName).value = value
            this.run()
            this.resetTrigger()

        }

    }

    resetTrigger() {

        // console.log(this.params)
        for (const [, value] of this.params) {
            if (value.type === FSM_PARAMS_TYPE_ENUM.TRIGGER) {
                value.value = false
            }
        }
    }
    get currentState() {
        return this._currentState

    }

    set currentState(newState) {
        if (!newState) {
            return
        }
        this._currentState = newState
        this._currentState.run()
    }


    //开始初始化他们了
    abstract init(): void
    //判断当前状态
    abstract run(): void

}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.4/manual/zh/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.4/manual/zh/scripting/decorator.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.4/manual/zh/scripting/life-cycle-callbacks.html
 */
